package com.masterclient.app.utils;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;

import com.eoner.baselib.utils.toast.ToastUtil;
import com.eoner.baselibrary.widget.PermissionDialog;
import com.masterclient.app.App;
import com.masterclient.app.R;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.lang.reflect.Method;

/**
 * @auther hjian
 * @date 2020/6/3.
 */
public class ScreenShotListenManager {

    String TAG = "========ScreenShot";

    private MediaContentObserver mInternalObserver;
    private MediaContentObserver mExternalObserver;
    private RxPermissions rxPermissions;
    private ScreenShotListener screenShotListener;

    public void setScreenShotListener(ScreenShotListener screenShotListener) {
        this.screenShotListener = screenShotListener;
    }

    public interface ScreenShotListener{
        void onScreenShot(String path);
    }

    private enum Singleton {
        INSTANCE;

        private ScreenShotListenManager singleton;

        Singleton() {
            singleton = new ScreenShotListenManager();
        }

        public ScreenShotListenManager getInstance() {
            return singleton;
        }
    }

    public static ScreenShotListenManager get() {
        return Singleton.INSTANCE.getInstance();
    }


    private Context mContext;
    private Handler mHandler;
    private Point mScreenRealSize;
    private Activity activity;

    public void setActivity(Activity activity) {
        this.activity = activity;
    }

    private ScreenShotListenManager() {
        mContext = App.getContext();//application context  自己想办法从自己项目中获取 也可以从外部调用传递
        mHandler = new Handler(App.getContext().getMainLooper());

        if (mScreenRealSize == null) {
            mScreenRealSize = getRealScreenSize();
        }
    }


    public void startListen() {
        Log.d(TAG, "startListen: ");
        // 创建内容观察者
        mInternalObserver = new MediaContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI, mHandler);
        mExternalObserver = new MediaContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mHandler);

        // 注册内容观察者
        mContext.getContentResolver().registerContentObserver(
                MediaStore.Images.Media.INTERNAL_CONTENT_URI,
                false,
                mInternalObserver
        );
        mContext.getContentResolver().registerContentObserver(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                false,
                mExternalObserver
        );
    }

    public void stopListen() {
        Log.d(TAG, "stopListen: ");
        if (mInternalObserver != null)
        mContext.getContentResolver().unregisterContentObserver(mInternalObserver);
        if (mExternalObserver != null)
        mContext.getContentResolver().unregisterContentObserver(mExternalObserver);
    }


    private class MediaContentObserver extends ContentObserver {

        private Uri mContentUri;

        public MediaContentObserver(Uri contentUri, Handler handler) {
            super(handler);
            mContentUri = contentUri;
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            if (activity != null) {
                rxPermissions = new RxPermissions(activity);
                boolean hasPermissions = rxPermissions.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE) && rxPermissions.isGranted(Manifest.permission.READ_EXTERNAL_STORAGE);
                if (!hasPermissions){
                    new PermissionDialog(activity, "开启相册权限", "保存图片需要获取保存到相册权限，请在下一个页面点击“允许”",
                                         R.mipmap.icon_permission_storage, () -> requestPermissions(mContentUri)).show();
                }else {
                    handleMediaContentChange(mContentUri);
                }
            }
        }
    }

    private void requestPermissions(Uri mContentUri){
        rxPermissions
                .requestEach(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
                .subscribe(permission -> { // will emit 2 Permission objects
                    if (permission.granted) {
                        handleMediaContentChange(mContentUri);
                    } else if (permission.shouldShowRequestPermissionRationale) {
                        ToastUtil.showToast("权限申请失败,无法截屏分享");
                    } else {
                        ToastUtil.showToast("权限申请失败,无法截屏分享");
                    }
                });
    }


    private void handleMediaContentChange(Uri contentUri) {
        Cursor cursor = null;
        try {
            // 数据改变时查询数据库中最后加入的一条数据
            cursor = mContext.getContentResolver().query(
                    contentUri,
                    Build.VERSION.SDK_INT < 16 ? MEDIA_PROJECTIONS : MEDIA_PROJECTIONS_API_16,
                    null,
                    null,
                    MediaStore.Images.ImageColumns.DATE_ADDED + " desc limit 1"
            );

            if (cursor == null) {
                Log.e(TAG, "Deviant logic.");
                return;
            }
            if (!cursor.moveToFirst()) {
                Log.d(TAG, "Cursor no data.");
                return;
            }

            // 获取各列的索引
            int dataIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            int dateTakenIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_TAKEN);
            int widthIndex = -1;
            int heightIndex = -1;
            if (Build.VERSION.SDK_INT >= 16) {
                widthIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.WIDTH);
                heightIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.HEIGHT);
            }

            // 获取行数据
            String data = cursor.getString(dataIndex);
            long dateTaken = cursor.getLong(dateTakenIndex);
            int width = 0;
            int height = 0;
            if (widthIndex >= 0 && heightIndex >= 0) {
                width = cursor.getInt(widthIndex);
                height = cursor.getInt(heightIndex);
            } else {
                // API 16 之前, 宽高要手动获取
                Point size = getImageSize(data);
                width = size.x;
                height = size.y;
            }
            Log.e("====","======="+mScreenRealSize.x+"==="+mScreenRealSize.y);
//            ToastUtil.showToast(data);
            int duration = 0;
            if (!checkScreenShot(data,dateTaken,width,height)&duration<=500){
                try {
                    duration += 100;
                    Thread.sleep(100);
                }catch (Exception ex){
                    ex.printStackTrace();
                }
            }
            if (checkScreenShot(data,dateTaken,width,height)) {
                screenShotListener.onScreenShot(data);
                Log.e("=======Data", "ScreenShot: path = " + data + "; size = " + width + " * " + height
                        + "; date = " + dateTaken);
//            }else {
//                Log.e("=======NoData", "ScreenShot: path = " + data + "; size = " + width + " * " + height
//                        + "; date = " + dateTaken);
            }

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            if (cursor != null && !cursor.isClosed()) {
                cursor.close();
            }
        }
    }

    private Point getImageSize(String imagePath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePath, options);
        return new Point(options.outWidth, options.outHeight);
    }


    private Point getRealScreenSize() {
        Point screenSize = null;
        try {
            screenSize = new Point();
            WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
            Display defaultDisplay = windowManager.getDefaultDisplay();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                defaultDisplay.getRealSize(screenSize);
            } else {
                try {
                    Method mGetRawW = Display.class.getMethod("getRawWidth");
                    Method mGetRawH = Display.class.getMethod("getRawHeight");
                    screenSize.set(
                            (Integer) mGetRawW.invoke(defaultDisplay),
                            (Integer) mGetRawH.invoke(defaultDisplay)
                    );
                } catch (Exception e) {
                    screenSize.set(defaultDisplay.getWidth(), defaultDisplay.getHeight());
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return screenSize;
    }

    private boolean checkScreenShot(String data, long dateTaken, int width, int height) {

        if (mScreenRealSize != null) {
            // 如果图片尺寸超出屏幕, 则认为当前没有截屏
            if (width > mScreenRealSize.x
                    || height > mScreenRealSize.y ) {
                return false;
            }
        }

        if (System.currentTimeMillis() - dateTaken > 10 * 1000) {
            return false;
        }

        if (TextUtils.isEmpty(data)) {
            return false;
        }

        data = data.toLowerCase();
        // 判断图片路径是否含有指定的关键字之一, 如果有, 则认为当前截屏了
        for (String keyWork : KEYWORDS) {
            if (data.contains(keyWork)) {
                return true;
            }
        }
        return false;
    }



    private static final String[] MEDIA_PROJECTIONS = {
            MediaStore.Images.ImageColumns.DATA,
            MediaStore.Images.ImageColumns.DATE_TAKEN,
    };

    private static final String[] MEDIA_PROJECTIONS_API_16 = {
            MediaStore.Images.ImageColumns.DATA,
            MediaStore.Images.ImageColumns.DATE_TAKEN,
            MediaStore.Images.ImageColumns.WIDTH,
            MediaStore.Images.ImageColumns.HEIGHT,
    };

    private static final String[] KEYWORDS = {
            "screenshot", "screen_shot", "screen-shot", "screen shot",
            "screencapture", "screen_capture", "screen-capture", "screen capture",
            "screencap", "screen_cap", "screen-cap", "screen cap"
    };
}
